\section{Our technique}

\subsection{Representation of method combinations}

We introduce a class named \texttt{method-combination-template}.  An
instance of this class represents all method combinations with the
same \emph{name}, independent of the options.  There is a template for
\texttt{standard}, a template for \texttt{and}, etc.  Furthermore, in
order to respect the restriction required by the standard, we
introduce a class \texttt{standard-method-combination} which is a
subclass of \texttt{method-combination}.  All method-combination
metaobjects are direct instances of this subclass.  There are no
subclasses of \texttt{standard-method-combination}, neither for
specific method-combination types, nor for distinguishing between
method combinations defined by the long and the short form of
\texttt{define-method-combination}.  In other words, a method
combination is a \emph{variant} of a method-combination template.  The
template contains a list of all its variants in use.

A method-combination instance contains the following slots:

\begin{itemize}
\item A reference to its template.
\item The list of method-combination \emph{options} to be given to
  \texttt{find-method-combination}, and that typically appear after
  the method-combination name of the \texttt{:method\-combination}
  \texttt{defgeneric} option.
\item The method-combination procedure.  This procedure has two
  parameters, both required.  The first parameter is a generic
  function for which an effective method is to be computed.  The
  second parameter is a list of pairs.  Each pair contains an
  applicable method, and a list of method \emph{qualifiers} for that
  method.  The result of applying the method-combination procedure is
  a form called the \emph{effective method}.  Notice that the
  method-combination procedure does \emph{not} have the
  method-combination options in its lambda list.
\item A list of generic functions that contain this method combination.
\end{itemize}

\subsection{When \texttt{find-method-combination} is called}

The expansion of the \texttt{defgeneric} macro contains a call to the
ordinary function \texttt{ensure-generic-function}.  If the
\texttt{:method-combination} option is explicitly supplied to the call
to \texttt{defgeneric}, then the call to
\texttt{ensure-generic-function} contains an explicit keyword argument
\texttt{:method-combination} with the value form being a call to the
generic function \texttt{find-method-combination} with the generic
function, the name of the method-combination type, and the options.
If no \texttt{:method-combination} option is given in the
\texttt{defgeneric} form, the \texttt{:method-combination} keyword
argument to the call to \texttt{ensure-generic-function} is not supplied.

The call to \texttt{find-method-combination} either returns an existing
method-combination instance corresponding to the type and the options
given, or it creates and stores a new such instance.  If the options
are incompatible with the method-combination template, a warning is
signaled, and the method-combination procedure is one that signals an
error if invoked.  The mechanism for detecting this incompatibility is
described later in this section.

A call to \texttt{ensure-generic-function} results in a call to
\texttt{ensure-generic-function-using-class} where the first argument
is either an existing generic function or \texttt{nil} if no generic
function with the given name exists.  The method on
\texttt{ensure-generic-function-using-class} specialized to the class
\texttt{null} supplies the \texttt{standard} method-combination as a
default value of the \texttt{:method-combination} when calling
\texttt{make-instance} to create a new generic function.

To detect whether a list of method-combination options are invalid for
a particular method-combination template, we analyze the
\emph{lambda-list} given in the long form of
\texttt{define-method\-combination}.  The analysis consists of
extracting all parameters that can be referenced in the
method-combination procedure.  We then construct a lambda expression
as follows:

\begin{verbatim}
(lambda (...)
  (list v1 v2 ... vn))
\end{verbatim}

\noindent
which is then compiled so that a function is obtained.  The lambda
list of this function is the lambda list that appears in the
\texttt{define-method-combination} form and \texttt{v1}, \texttt{v2},
..., \texttt{vn} are the lexical variables resulting from our analysis
of the lambda list.  Applying this function to the options given to
the \texttt{find-method-combination} function returns a list of
objects.  The lambda list typically contains \texttt{\&aux} lambda
list keywords, with forms that check the validity of the options
supplied, and signal an error whenever an invalid option combination
is detected.  Thus, if either the lambda list is incompatible with the
options given, or one of these \texttt{\&aux} forms detects an invalid
option combination, an error is signaled.  We handle this error, turn
it into a warning, and return a method-combination instance with a
method-combination procedure that signals an error whenever invoked.

This technique for detecting incompatible or invalid options handles
the first scenario described in \refSec{sec-introduction}.  When the
user corrects the incorrect form that created or reinitialized the
generic function (typically a \texttt{defgeneric} form), the
validation process is re-invoked and a method-combination with a
viable method-combination procedure is assigned to the generic
function.  This technique also detects the second scenario described
in \refSec{sec-introduction}.  The way the user can correct the
situation in this scenario is described below.

When the options given to \texttt{find-method-combination} are
compatible and valid, a viable method-combination procedure is
constructed as follows:

\begin{verbatim}
(lambda (generic-function method-qualifier-pairs)
  (let ((v1 ...) (v2 ...) ... (vn ...))
    <body>))
\end{verbatim}

\noindent
where \texttt{v1}, \texttt{v2}, ..., \texttt{vn} are again the lexical
variables resulting from our analysis of the lambda list.  The
initialization forms for the variables are the values returned in the
resulting list of our analysis function.

\subsection{Redefining a method-combination type}

When a \texttt{define-method-combination} form is re-evaluated, we
locate the corresponding method-combination template.  We then invoke
the same analysis as before to every variant, i.e., to every existing
method combination having this type name.  If an analysis fails, we
then signal a warning containing all generic functions using the now
invalid method-combination, and we set the method-combination
procedure of the invalid method combination to one that will signal an
error when invoked.  If the analysis succeeds, then the corresponding
method combination is assigned a viable method-combination procedure.

\subsection{Expanding the short form to the long form}

As mentioned in \refSec{sec-introduction}, it is not obvious how to
transform the short form of \texttt{define-method-combination} into
the long form.  Recall that the syntax of the short form is:
\vskip 0.1cm
\noindent
\texttt{(define-method-combination} \textit{name [[short-form-options]]}\texttt{)}

where a \textit{short-form-option} can be:

\begin{itemize}
\item \texttt{:documentation} \textit{documentation}
\item \texttt{:identity-with-one-argument}\\ \textit{identity-with-one-argument}
\item \texttt{:operator} \textit{operator}
\end{itemize}

Here, \textit{documentation} is a string that is not evaluated.  When
the short form gets turned into the long form, it becomes an ordinary
documentation string, preceding the forms of the body of the long
form.

To illustrate where the remaining options end up in the long form,
recall the following example from the dictionary entry for
\texttt{define-method-combination}, where both the short form and the
long form are used to define the built-in method-combination
\texttt{and}.  We have changed only the layout of the code so that it
will fit on the page.

\noindent
The short form is:

{\small\begin{verbatim}
(define-method-combination and
  :identity-with-one-argument t)
\end{verbatim}}

\noindent
The long form is;

{\small\begin{verbatim}
(define-method-combination and
        (&optional (order :most-specific-first))
        ((around (:around))
         (primary (and) :order order :required t))
  (let ((form (if (rest primary)
                  `(and ,@(mapcar
                            #'(lambda (method)
                                `(call-method ,method))
                            primary))
                  `(call-method ,(first primary)))))
    (if around
        `(call-method ,(first around)
                      (,@(rest around)
                       (make-method ,form)))
        form)))
\end{verbatim}}

\noindent
The option \textit{identity-with-one-argument} is responsible for the
form:

{\small\begin{verbatim}
(if (rest primary)
    `(and ,@(mapcar
              #'(lambda (method)
                  `(call-method ,method))
              primary))
    `(call-method ,(first primary)))))
\end{verbatim}}

\noindent
Had this option been \texttt{nil} or not present, the corresponding
form would have looked like this instead:

{\small\begin{verbatim}
`(and ,@(mapcar
          #'(lambda (method)
              `(call-method ,method))
          primary))
\end{verbatim}}

\noindent
In order for our technique to work for the short form, when we express
the short form in terms of the long form, we modify the lambda list of
the long form compared to the example above as follows:

{\small\begin{verbatim}
(&optional (order :most-specific-first)
 &aux (ignore (unless (member order
                              '(:most-specific-first
                                :most-specific-last))
                (error ....))))
\end{verbatim}}

\noindent
Now, any attempt to call a function with this lambda list with
a number of arguments other than exactly 1, or with one argument that
is neither \texttt{:most-specific-first} nor
\texttt{:most-specific-last} will fail.
